
import 'package:dio/dio.dart';
import 'package:flutter_menu/app_config.dart';
import 'package:flutter_menu/data/menu_api.dart';
import 'package:flutter_menu/data/mock.dart';
import 'package:flutter_menu/data/obx_store.dart';
import 'package:flutter_menu/model/app_update_model.dart';
import 'package:flutter_menu/model/menu_model.dart';
import 'package:flutter_menu/model/net_result.dart';
import 'package:flutter_menu/model/order_model.dart';
import 'package:flutter_menu/model/shope_model.dart';
import 'package:flutter_menu/objectbox.g.dart' as obj;
import 'package:get/get.dart';

import '../exception/account_exception.dart';
import '../model/login_model.dart';

class MenuRepository {
   MenuApi _menuApi = MenuApi(Get.find<Dio>(), baseUrl: Get.find<AppConfig>().config.url);

  static final MenuRepository _repository = MenuRepository._();

  final obj.Store _store = Get.find<obj.Store>();

  static MenuRepository get instance => _repository;

  MenuRepository._();

  void changeApiUrl(){
    _menuApi = MenuApi(Get.find<Dio>(), baseUrl: Get.find<AppConfig>().config.url);
  }

  Future<SyncResModel> syncMenu(String shopId, {String? type}) async {
    var res = await _menuApi.getSyncData("token", "");
    var data = res.result_data();
    data.update(store);
    return data;
  }

  Future<SyncResModel> mockSync(String shopId, {String? type}) async {
    late NetResult<SyncResModel> _value;
    try {
      _value = NetResult<SyncResModel>.fromJson(
        info,
            (json) => SyncResModel.fromJson(json as Map<String, dynamic>),
      );
    } on Object catch (e, s) {
      e.printError();
      rethrow;
    }
    var data =  _value.result_data();
    data.update(store);
    return data;
  }

  Future<SyncResModel> _getDataFromNet(String shopId, {String? type, String? token}) async {
    // var res = await _menuApi.getSyncData("token", type);
    // return res.result_data();
    return Future.value(SyncResModel());
    return mockSync("");
  }

  Future<UserModel?> loginByNet(LoginReq req, String account, String pwd,{bool clean = false}) async {
    UserModel? user;
    var res = await _menuApi.bind(req);
    var token = res.result_data();
    SyncResModel data =
        await _getDataFromNet(req.shopId, type: SyncResModel.TYPE_USER_LIST, token: token);
    var resUsers =  data.userList??[];
    var userList =
        resUsers.where((v) => (v.username == account) && (v.password == pwd)).toList();
    if (userList.isNotEmpty) {
      user = userList[0];
      if(!user.isAllowLoginDevice()) throw AccountNoPermissionException();
      if(clean ) _store.removeAll();
      AppConfig.instance.storeId = req.shopId;
      AppConfig.instance.token = token;
      data.upUserList(store);
    }

    return user;
  }

  Future<UserModel?> loginByDB(LoginReq req, String account, String pwd) {
    UserModel? user = _store.login(account, pwd);
    if(user!=null && !user.isAllowLoginDevice()) throw AccountNoPermissionException();
    _getDataFromNet(req.shopId, type: SyncResModel.TYPE_USER_LIST).then((v) {
      v.upUserList(store);
    });
    return Future.value(user);
  }

  Future<List<ShopTableInfoModel>> getTables() {
    return _store.box<ShopTableInfoModel>().getAllAsync()
        .then((v) {
          for(var e  in v){
            e.tables.sort((a,b)=> a.sort > b.sort? 1:-1);
          }
          v.sort((a,b)=> a.sort > b.sort? 1:-1);

          return v;
    });
  }


  Future<ShopModel?> getShopInfo(){
    return _store.box<ShopModel>().getAllAsync().then((v) => v.isEmpty?null: v[0]);
  }

  Future<AppVersion> getAppVersion() async{
    var res =  await _menuApi.getAppVersion(AppConfig.instance.storeId??"");
    var data = res.result_data();
    return data;
  }


  Future<OrderResp> order(OrderRq rq){
    return _menuApi.order(rq)
        .then((v) => v.result_data());
  }

  Future<List<OrderRecordResp>?> getOrderRecordByTableId(String tableId){
    return _menuApi.getOrderRecordList({
      "tableUuid":tableId,
      "userUuid":AppConfig.instance.loginModel?.id
    })
        .then((v)=> v.result_data().rows);
  }

}
